﻿

IncludePath "Source/"
IncludeFile "threeD.pb"
IncludePath "/"

EnableExplicit

;{ Constants
	#VertexsMax = 1000
	#LAYOUT_VERTEX_POS = 1
;}
;{ Structures
	Structure vertex
		pos.vec3
	EndStructure
;}
;{ Globals
	Global Dim VertexData.vertex(#VertexsMax)
	Global VertexsAmount.l
	Global shaderID.l
	Global GeometryID.l
	Global hDC.l
	Global MatProj.mat4
	Global MatModel.mat4
;}
;{ Procedures
	Procedure SetVertex(*vertex.vertex, x.f, y.f, z.f)
		*vertex\pos\x = x
		*vertex\pos\y = y
		*vertex\pos\z = z
	EndProcedure
	Procedure NewVertex(x.f, y.f ,z.f)
		Protected.l n
		n = VertexsAmount
		SetVertex(@VertexData(n), x, y, z)
		n = n + 1
		VertexsAmount = n
	EndProcedure
	Procedure.l CreateGeometry()
		Protected.l idVAO, idVBO
		NewVertex(-1.0, -1.0, 0.0)
		NewVertex( 1.0, -1.0, 0.0)
		NewVertex(-1.0,  1.0, 0.0)
		NewVertex( 1.0, -1.0, 0.0)
		NewVertex( 1.0,   1.0, 0.0)
		NewVertex(-1.0,  1.0, 0.0)
		
		; create empty VAO and VBO
		glGenVertexArrays(1, @idVAO)
		glBindVertexArray(idVAO)
		glGenBuffers(1, @idVBO)
		
		; fill VBO by our vertices
		glBindBuffer(#GL_ARRAY_BUFFER, idVBO)
		glBufferData(#GL_ARRAY_BUFFER, VertexsAmount*SizeOf(vertex), @VertexData(), #GL_STATIC_DRAW)
		
		;setup vertex attributes in VBO
		glVertexAttribPointer(#LAYOUT_VERTEX_POS, 3, #GL_FLOAT, #GL_FALSE, SizeOf(vertex), OffsetOf(vertex\pos))
		glEnableVertexAttribArray(#LAYOUT_VERTEX_POS)
		
		ProcedureReturn idVAO
	EndProcedure
	Procedure UpdateModelMat()
		Protected.vec4 pos, Q
		Protected.mat3 MatModel_
		Protected.f angle
		Protected.vec3 vAxe
		Vec3_Set(vAxe, 0, 1, 0)
		angle = timeGetTime_()/1000
		Quat_FromAxis(Q, vAxe, angle)
		Mat3_FromQuat(MatModel_, Q)
		Vec4_Set(pos, 0, 0, -3, 1)
		Mat4_SetM(MatModel, MatModel_, pos)
	EndProcedure
	Procedure Init()
		UsePNGImageDecoder()
		OpenWindow(0, 100, 200, 512, 512, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget|#PB_Window_ScreenCentered)
		hDC = CreateOpenGLContext(WindowID(0))		
		ShaderID = LoadShadersFromFiles("Data/ex01_shader.vs", "Data/ex01_shader.fs")
		GeometryID = CreateGeometry()
		UpdateModelMat()
	EndProcedure
	Procedure RenderScene()
		Protected.l uniformLocation
		glUseProgram(shaderID)
		uniformLocation = glGetUniformLocation(shaderID, @"Noize")
		If uniformLocation <> -1
			glUniform1f(uniformLocation, GetTickCount_()*0.001)
		EndIf
		uniformLocation = glGetUniformLocation(shaderID, @"mProj")
		If uniformLocation <> -1
			glUniformMatrix4fv(uniformLocation, 1, #True, @MatProj)
		EndIf
		uniformLocation = glGetUniformLocation(shaderID, @"mModel")
		If uniformLocation <> -1
			glUniformMatrix4fv(uniformLocation, 1, #True, @MatModel)
		EndIf
		glBindVertexArray(GeometryID)
		glDrawArrays_(#GL_TRIANGLES, 0, VertexsAmount)
	EndProcedure
	Procedure RunStart()
		Protected.l Event, Quit
		Repeat
			Event = WaitWindowEvent(1)
			Select Event
				Case #PB_Event_CloseWindow	
					Quit = 1
				Case #PB_Event_SizeWindow
					glViewport_(0, 0, WindowWidth(0), WindowHeight(0))
					Mat4_CreatePerspective(MatProj, #PI/2, WindowWidth(0)/WindowHeight(0), 1/10, 10)
			EndSelect
			glClearColor_(0.3,0.3,0.3,1)
			glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
			UpdateModelMat()
			RenderScene()
			SwapBuffers_(hDC)
		Until Quit = 1
	EndProcedure
;}



Init()
RunStart()


























; IDE Options = PureBasic 5.11 (Windows - x86)
; CursorPosition = 110
; FirstLine = 44
; Folding = c3-
; EnableXP
; EnableCompileCount = 228
; EnableBuildCount = 0
; EnableExeConstant